﻿using System.Windows;
using Microsoft.Phone.Scheduler;
using System.Device.Location;
using System;
using Microsoft.Phone.Info;
using System.Net;
using System.IO;
using Microsoft.Phone.Shell;
using System.Collections.Generic;
using System.Linq;

namespace PositionsAgent
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        private static volatile bool _classInitialized;
        public static bool _updateTile = false;

        /// <remarks>
        /// ScheduledAgent constructor, initializes the UnhandledException handler
        /// </remarks>
        public ScheduledAgent()
        {
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                });
            }
        }

        /// Code to execute on Unhandled Exceptions
        private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

        /// <summary>
        /// Agent that runs a scheduled task
        /// </summary>
        /// <param name="task">
        /// The invoked task
        /// </param>
        /// <remarks>
        /// This method is called when a periodic or resource intensive task is invoked
        /// </remarks>
        protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background

            //NotifyComplete();


            GeoCoordinateWatcher GeoCoordinateWatcher = new GeoCoordinateWatcher();
            bool ok = GeoCoordinateWatcher.TryStart(false, new TimeSpan(0, 0, 10));
            if (ok)
            {
                UpdatePosition(GeoCoordinateWatcher.Position.Location);
                if(_updateTile)
                    UpdateAppTile(GeoCoordinateWatcher.Position.Location);
            }
        }

        public static void UpdateAppTile(GeoCoordinate g)
        {
            ShellTile appTile = ShellTile.ActiveTiles.FirstOrDefault();

            var message = string.Format("Lat: {0}, Log: {1}, {2}", Math.Round(g.Latitude,2), Math.Round(g.Longitude,2), DateTime.Now);

            if (appTile != null)
            {
                StandardTileData tileData = new StandardTileData
                {
                    BackContent = message
                };

                appTile.Update(tileData);
            }
        }
        

        private void UpdatePosition(GeoCoordinate g)
        {
            Console.WriteLine(g);

            var url = "http://fboscari.altervista.org/SendGPSPosition.php?uid=" +
                getID();
            url += "&lat=" + g.Latitude;
            url += "&log=" + g.Longitude;

            getHTML(url, (s) => {
                Console.WriteLine(s);
            }, (e) => {
                Console.WriteLine(e.ToString());
            });
        }

        

        public static string getID()
        {
            byte[] result = null;
            object uniqueId;
            if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
                result = (byte[])uniqueId;
            var s = "";
            for (int i = 0; i < result.Length; i++)
                s += result[i];
            return s;
        }

        public static void getHTML(string query, Action<string> callback, Action<Exception> error)
        {
            try
            {
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(query);
                req.Method = "GET";
                req.BeginGetResponse(
                    (asyncResult) =>
                    {
                        try
                        {
                            HttpWebResponse objResponse = null;
                            StreamReader objs = null;

                            HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;

                            objResponse = (HttpWebResponse)request.EndGetResponse(asyncResult);
                            objs = new StreamReader(objResponse.GetResponseStream());

                            var s = objs.ReadToEnd();
                            if (callback != null)
                                callback(s);

                            return;
                        }
                        catch (Exception e)
                        {
                            e.ToString();
                            error(e);
                        }
                    }
                    , req);
            }
            catch (Exception e)
            {
                error(e);
            }
        }
    }
}